#include <iostream>
#include <string>
#include <cstdlib>
#include <cassert>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <pthread.h>
#include<cstdarg>
#include "logMessage.hpp"

using std::cin;
using std::cout;
using std::endl;
using std::getline;
using std::string;

void* recverAndPrint(void* args)
{
    while(true)
    {
        int sockFd=*(int*)args;
        char buffer[1024];
        struct sockaddr_in temp;
        socklen_t templen=sizeof(temp);
        ssize_t s=recvfrom(sockFd,buffer,sizeof(buffer),0,(struct sockaddr*)&temp,&templen);
        if(s>0)
        {
            buffer[s]=0;
            cout<<buffer<<endl;
        }
    }
}

static void Usage(const string proc){
    cout<<"Usage::\n\t"<<proc<<"server_IP server_Port nick_Name";
}

int main(int argc,char* argv[])
{
    if(argc!=4)
    {
        Usage(argv[0]);
        exit(1);
    }
    string server_IP = argv[1];
    uint16_t server_Port = atoi(argv[2]);
	string nick_Name = argv[3];
    int sockFd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockFd < 0) {
        logMessage(FATAL, "socket() faild:: %s : %d", strerror(errno), sockFd);
        exit(2);
    }
    logMessage(DEBUG, "socket create success: %d", sockFd);
    struct sockaddr_in server;
    bzero(&server, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(server_Port);
    server.sin_addr.s_addr = inet_addr(server_IP.c_str());

    pthread_t t;
    pthread_create(&t,nullptr,recverAndPrint,&sockFd);
    while(true)
    {
        std::cerr<<"please enter>>";
        string inBuffer;
        inBuffer +="[";
        inBuffer +=nick_Name;
        inBuffer +="]# ";
        string tempS;
        getline(cin,tempS);
        inBuffer +=tempS;
        sendto(sockFd, inBuffer.c_str(), inBuffer.size(), 0,
               (const struct sockaddr*)&server, sizeof(server));
    }
    close(sockFd);
    return 0;
}
